package com.yanfan.protocol.serialPort;

import com.fazecast.jSerialComm.SerialPort;
import com.yanfan.protocol.serialPort.config.SerialPortCondition;
import com.yanfan.protocol.serialPort.config.SerialPortProperties;
import com.yanfan.protocol.serialPort.serialPort.SerialPortCallback;
import com.yanfan.protocol.serialPort.serialPort.SerialPortListener;
import com.yanfan.protocol.serialPort.serialPort.SerialPortManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
@EnableScheduling
public class SerialPortOpen/* implements CommandLineRunner*/ {
    @Value("${serial-port.portName}")
    private String portName;
    @Value("${serial-port.isOpen}")
    private boolean isOpen;

    private static final Logger logger = LoggerFactory.getLogger(SerialPortOpen.class);

  /*  public static final int SERIAL_BAUD_RATE = 115200;
    public static volatile boolean SERIAL_PORT_STATE = false;

    public static volatile SerialPort SERIAL_PORT_OBJECT = null;*/

    public static volatile boolean isExit = false;

    @Conditional(SerialPortCondition.class)
    @Bean
    public void SerialPortOpen(){
        try {
            //  win
            //SerialPortManager.connectSerialPort("COM1");
            SerialPortManager.connectSerialPort(portName);
            //  linux centos
            //SerialPortManager.connectSerialPort("ttyS1");
        } catch (Exception e) {
            System.out.println(e.toString());
        }
    }

//    @Override
//    public void run(String... args) throws Exception {
//        if (isOpen != false) {
//            /*Thread thread = new Thread(() -> {
//
//            });
//            // 设置线程的优先级
//            //thread.setPriority(Thread.MAX_PRIORITY);
//            thread.start();*/
//
//            try {
//                //  win
//                //SerialPortManager.connectSerialPort("COM1");
//                SerialPortManager.connectSerialPort(portName);
//                //  linux centos
//                //SerialPortManager.connectSerialPort("ttyS1");
//            } catch (Exception e) {
//                System.out.println(e.toString());
//            }
//        }
//
//    }

    @PreDestroy
    public void destroy() {
        SerialPortManager.closeSerialPort();
    }


    @Scheduled(cron = "0/5 * * * * ?")
    public void reconnect() {
        if (isOpen) {
            List<String> serialPortList = SerialPortManager.getSerialPortList();
            if (serialPortList.size() > 0) {
                serialPortList.stream().forEach(port -> {
                    if (port.equals(portName)) {    //判断端口是否存在
                        isExit = true;
                        try {
                            SerialPort serialPort = SerialPortManager.openSerialPort(portName, SerialPortProperties.getStaticBaudRate());
                            TimeUnit.MILLISECONDS.sleep(2000);
                            //给当前串口对象设置监听器
                            serialPort.addDataListener(new SerialPortListener(new SerialPortCallback()));
                            if (serialPort.isOpen()) {
                                SerialPortManager.SERIAL_PORT_OBJECT = serialPort;
                                SerialPortManager.SERIAL_PORT_STATE = true;
                                SerialPortManager.closeSerialPort();
                                logger.info("有可用的" + portName + "，尝试重新连接中........");
                                //System.out.println("有可用的" + portName + "，尝试重新连接中........");
                                SerialPortOpen.connectSerialPort(portName);
                            } else if (!SerialPortManager.SERIAL_PORT_STATE) {
                                logger.info("端口被占用，打开" + portName + "失败！");
                                //System.out.println("端口被占用，打开" + portName + "失败！");
                            }
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }
                    }
                });
                if (!isExit) {
                    logger.info("没有可用的" + portName + "，连接串口失败！");
                    //System.out.println("没有可用的" + portName + "，连接串口失败！");
                }
            }
        }
    }


    //  连接串口
    public static void connectSerialPort(String portName) {
        try {
            SerialPort serialPort = SerialPortManager.openSerialPort(portName, SerialPortProperties.getStaticBaudRate());
            TimeUnit.MILLISECONDS.sleep(2000);
            //给当前串口对象设置监听器
            serialPort.addDataListener(new SerialPortListener(new SerialPortCallback()));
            if (serialPort.isOpen()) {
                SerialPortManager.SERIAL_PORT_OBJECT = serialPort;
                SerialPortManager.SERIAL_PORT_STATE = true;
                logger.info(portName + "-- 串口，尝试重连成功！");
                //System.out.println(portName + "-- 串口，尝试重连成功！");
            }
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }


}
